<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Example: Compose Classes of Objects with &#x60;augment&#x60;</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
    <link rel="stylesheet" href="../assets/css/main.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <script src="../../build/yui/yui-min.js"></script>
</head>
<body>

<div id="doc">
    <h1>Example: Compose Classes of Objects with &#x60;augment&#x60;</h1>

    
        <a href="#toc" class="jump">Jump to Table of Contents</a>
    

    <div class="yui3-g">
        <div id="main" class="yui3-u">
            <div class="content"><div class="intro">
<p>Creating a composition-based class structure using <code>augment</code></p>
</div>

<div class="example">
    <script>
YUI().use('node', function(Y) {

YUI().use('node', function(Y) {
    // This method is in the 'oop' module.  Since we require 'node'
    // for this example, and 'node' requires 'oop', the 'oop' module
    // will be loaded automatically.

    var Foo = function() {
        /* code specific to Foo */
        this.publish('interestingMoment');
    };

    Foo.prototype.doSomething = function() {

        var eventData = {};

        // -- do something interesting, add results to eventData --

        eventData.statusText = 'bar';

        // notify the subscribers, passing the event data
        this.fire('interestingMoment', eventData);
    }

    Y.augment(Foo, Y.EventTarget);

    var foo = new Foo();

    // add some event listeners
    foo.on('interestingMoment', function (data) {
        var p = Y.one('#demo_p1');
        p.setContent('I was notified of an interesting moment: ' + data.statusText);
    });

    foo.on('interestingMoment', function (data) {
        var p = Y.one('#demo_p2');
        p.setContent('I was also notified of an interesting moment: ' + data.statusText);
    });

    Y.on('click', function() { 
        foo.doSomething();
    }, '#demo');
});


});
</script>

<div id="demo">
<input type="button" id="demo" name="demo" value="Send">

<p id="demo_p1"></p>
<p id="demo_p2"></p>
</div>

</div>


<h3 id="using-augment">Using <code>augment</code></h3>

<pre class="code prettyprint">YUI().use(&#x27;node&#x27;, function(Y) {
    &#x2F;&#x2F; This method is in the &#x27;oop&#x27; module.  Since we require &#x27;node&#x27;
    &#x2F;&#x2F; for this example, and &#x27;node&#x27; requires &#x27;oop&#x27;, the &#x27;oop&#x27; module
    &#x2F;&#x2F; will be loaded automatically.</pre>


<h3 id="the-example-any-class-can-be-an-eventtarget">The example: Any class can be an <code>EventTarget</code></h3>

<p>This example creates a custom class, then augments it with
<code>EventTarget</code>. Using the packaged functionality of <code>EventTarget</code>, the code for
<code>Foo</code> is able to focus on the functionality unique to its
purpose.</p>

<pre class="code prettyprint">YUI().use(&#x27;node&#x27;, function(Y) {
    &#x2F;&#x2F; This method is in the &#x27;oop&#x27; module.  Since we require &#x27;node&#x27;
    &#x2F;&#x2F; for this example, and &#x27;node&#x27; requires &#x27;oop&#x27;, the &#x27;oop&#x27; module
    &#x2F;&#x2F; will be loaded automatically.

    var Foo = function() {
        &#x2F;* code specific to Foo *&#x2F;
        this.publish(&#x27;interestingMoment&#x27;);
    };

    Foo.prototype.doSomething = function() {

        var eventData = {};

        &#x2F;&#x2F; -- do something interesting, add results to eventData --

        eventData.statusText = &#x27;bar&#x27;;

        &#x2F;&#x2F; notify the subscribers, passing the event data
        this.fire(&#x27;interestingMoment&#x27;, eventData);
    }

    Y.augment(Foo, Y.EventTarget);

    var foo = new Foo();

    &#x2F;&#x2F; add some event listeners
    foo.on(&#x27;interestingMoment&#x27;, function (data) {
        var p = Y.one(&#x27;#demo_p1&#x27;);
        p.setContent(&#x27;I was notified of an interesting moment: &#x27; + data.statusText);
    });

    foo.on(&#x27;interestingMoment&#x27;, function (data) {
        var p = Y.one(&#x27;#demo_p2&#x27;);
        p.setContent(&#x27;I was also notified of an interesting moment: &#x27; + data.statusText);
    });

    Y.on(&#x27;click&#x27;, function() { 
        foo.doSomething();
    }, &#x27;#demo&#x27;);
});</pre>


<h3 id="composition-not-inheritance">Composition, not inheritance</h3>
<p>If <code>Foo</code> were a part of a class hierarchy, it would be improper
to include <code>EventTarget</code> in the inheritance chain, because its custom event
functionality is not an intrinsic characteristic but rather an ancillary, generic
capability that many classes share.</p>

<p>Unlike <code>extend</code>ed classes, the relationship between a class and
the classes augmenting it is not an indication of type hierarchy.  The intent
of <code>augment</code> is to aid in extracting nonessential behaviors or
behaviors shared by many classes, allowing for a composition-style class
architecture.</p>

<img src="../assets/yui/composition_diagram.png" alt="Diagram showing class hierarchy, highlighting has-a relationship"/>

<p>This may appear similar to multiple inheritance, but it's not.
<code>augment</code> simply adds the public methods and members from one class
prototype to another class prototype.  Instances of the augmented class will
not pass <code>instanceof</code> tests for the class(es) which augmented
it.</p>

<pre class="code prettyprint">YUI().use(&#x27;oop&#x27;, function(Y) {

    function Foo() {}
    Foo.prototype.doSomething = function () { &#x2F;* something *&#x2F; };

    function Bar() {}
    Y.augment(Bar, Foo);

    var b = new Bar();
    if (b instanceof Bar) {} &#x2F;&#x2F; true 
    if (b instanceof Foo) {} &#x2F;&#x2F; FALSE
});</pre>

</div>
        </div>

        <div id="sidebar" class="yui3-u">
            
                <div id="toc" class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Table of Contents</h2>
                    </div>

                    <div class="bd">
                        <ul class="toc">
<li>
<a href="#using-augment">Using <code>augment</code></a>
</li>
<li>
<a href="#the-example-any-class-can-be-an-eventtarget">The example: Any class can be an <code>EventTarget</code></a>
</li>
<li>
<a href="#composition-not-inheritance">Composition, not inheritance</a>
</li>
</ul>
                    </div>
                </div>
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                                    <li data-description="Setting up a YUI Instance">
                                        <a href="yui-core.html">YUI Core</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Working with multiple YUI instances.">
                                        <a href="yui-multi.html">Multiple Instances</a>
                                    </li>
                                
                            
                                
                                    <li data-description="On-demand loading of YUI and non-YUI assets">
                                        <a href="yui-loader-ext.html">YUI Loader - Dynamically Adding YUI and External Modules</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Create Class Hierarchies with &#x60;extend&#x60;">
                                        <a href="yui-extend.html">Create Class Hierarchies with &#x60;extend&#x60;</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Creating a composition-based class structure using &#x60;augment&#x60;">
                                        <a href="yui-augment.html">Compose Classes of Objects with &#x60;augment&#x60;</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Add behaviors to objects or static classes with &#x60;mix&#x60;">
                                        <a href="yui-mix.html">Add Behaviors to Objects with &#x60;mix&#x60;</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Combine data sets and create shallow copies of objects with &#x60;merge&#x60;">
                                        <a href="yui-merge.html">Combine Data Sets with &#x60;merge&#x60;</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Check data types with the &#x60;Lang Utilities&#x60;">
                                        <a href="yui-isa.html">Check Data Types with &#x60;Lang&#x60;</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Get information about the current user agent with &#x60;UA&#x60;">
                                        <a href="yui-ua.html">Browser Detection with &#x60;UA&#x60;</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Working with YUI 2 in 3">
                                        <a href="yui-yui2.html">Working with YUI 2 in 3</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Natively use YUI Gallery Modules">
                                        <a href="yui-gallery.html">Natively use YUI Gallery Modules</a>
                                    </li>
                                
                            
                        </ul>
                    </div>
                </div>
            

            
        </div>
    </div>
</div>

<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>

</body>
</html>
